<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/7/25
 * Time: 14:37
 */

namespace App\GameService;

use App\Enum\ZjhEnum;
use App\GameService\games\PlayHelp;
use App\WebSocket\WsBase;
use App\Common\AuthCommon;
use App\Common\GameCommon;
use App\Utility\BaseEnum;
use App\Common\BaseComm;

class Gamejinhua extends WsBase
{
    /**
     * TODO 玩家进入房间
     */
    public function play()
    {
        $gameOObject = $this->paramsBean->getGameObject();
        BaseEnum::Logger('实例化：整体 (getGameObject)--->>>' . json_encode($gameOObject), 'user-login');
        //刚进入游戏推送前端的数据
//        $gameResult = [
//            //游戏初始进入可见的一些属性
//            "gstart" => 0,//游戏状态
//            "gameNo" => "",//房间编号,动态生成
//            "maxRound" => 20,//最大回合数
//            "currRound" => 0,//当前回合
//            "deskMoney" => 0,//桌子上总筹码
//            //房间详情,game_room表里的字段不会随游戏进行变化,不写进静态变量
//            "roomInfo" => [],
//            //匹配的玩家列表
//            "players" => [],
//        ];
        $loginFd = $this->paramsBean->getFd();
        $data = $this->paramsBean->getData(true);
        $gameRId = isset($data['gameRoomId']) ? intval($data['gameRoomId']) : 0;
        $debugFlag = isset($data['debug']) ? intval($data['debug']) : 0;
        if (! $gameRId) {
            $this->ResError(BaseEnum::MSG_0XF2, "游戏类型参数丢失");
            return true;
        }
        $userid = 0;
        //TODO 登录验证
        $playerInfo = $this->LoginPlayUser($userid);
        if (!$playerInfo || $userid <= 0 ) { return FALSE; }
        
        
        
        // 获取在线的游戏列表数据；
        try {
            $gRoomInfo = BaseComm::GameRoomDetail($gameRId);
            BaseEnum::Logger("获取房间信息：Gamejinhua-(play)--roomid={$gameRId}->>>" . $gRoomInfo['gameId'].'--->>>'.json_encode($gRoomInfo), 'user-login');
            $gameId = isset($gRoomInfo["gameId"]) ? intval($gRoomInfo["gameId"]) : 0;
            $gameName = isset($gRoomInfo["gpKey"]) ? $gRoomInfo["gpKey"] : "";
            $roomLastPots = isset($gRoomInfo["smallPoints"]) ? floatval($gRoomInfo["smallPoints"]) : 0; // 房间的携带分要求；
            $roomEveryPots = isset($gRoomInfo["everyPoints"]) ? floatval($gRoomInfo["everyPoints"]) : 0; // 房间底分
//            $totalJu = isset($gRoomInfo["playNumber"]) ? intval($gRoomInfo["playNumber"]) : 1; // 至少玩几局
            if (empty($gRoomInfo) || $gameId <= 0) {
                throw new \Exception("获取房间信息异常", BaseEnum::MSG_0XF6);
            }

            $username = isset($playerInfo["name"]) ? $playerInfo["name"] : "";
            $login_points = isset($playerInfo["points"]) ? floatval($playerInfo["points"]) : 0;

            /*
             * 判断玩家是否掉线；
             * $playerInfo = AuthCommon::getLoginUser($loginFd);
             * $userid = isset($playerInfo["uid"]) ? intval($playerInfo["uid"]) :0 ;
             * if(empty($playerInfo) || $userid <= 0 || empty($username)){
             * $this-> ResError(BaseEnum::MSG_0XF7,"玩家未登录，或玩家已掉线请重试");
             * return true;
             * }
             */

            // 是否准入分
            if ($login_points <= 0 || $login_points < $roomLastPots || $roomEveryPots <= 0) {
                throw new \Exception("玩家游戏分达不到房间最低标准，退出房间!!", BaseEnum::MSG_0XF8);
            }
            // 写入玩家信息
            $wjInfo = array(
                "uid" => $userid,
                'name' => $username,
                "isNation" => isset($playerInfo['isNation']) ? intval($playerInfo['isNation']) : 0,  // 玩家身份信息
                "agentId" => isset($playerInfo['recUid']) ? intval($playerInfo['recUid']) : 0,   // 代理用户ID
                "pstatus" => 0,   //玩家操作状态
                "sex" => isset($playerInfo['gender']) ? intval($playerInfo['gender']) : 0, // 性别
                "head_id" => isset($playerInfo['head_url']) ? intval($playerInfo['head_url']) : 0, // 头像
                "fd" => $loginFd,
                "points" => $login_points,
                "seatNo" => - 1,  // 默认座位为0
            );

            // 查询是否有未开局房间；(等待开局，返回是否可以开)
            $getFreeRoom = $this->joinXYRooms($gameRId, $gRoomInfo, $wjInfo);
            $gameNo = isset($getFreeRoom["roomNo"]) ? $getFreeRoom["roomNo"] : ""; // 房间编号内容

            // 通知在线的其它用户；有新玩家上线
            $players = isset($getFreeRoom['info']) ? $getFreeRoom['info'] : false; // 玩家信息；
            BaseEnum::Logger('匹配完成返回玩家信息--->>>' . json_encode($players), 'user-login');
            if (isset($getFreeRoom) && ! empty($getFreeRoom) && isset($getFreeRoom['ifOpen']) && intval($getFreeRoom['ifOpen']) > 0 && ! empty($getFreeRoom['info'])) {
                BaseEnum::Logger('匹配成功：可以开局---->>>加入房间成功', 'user-login');
                /************************************需要开局插入DB的游戏**********************************/
                $gRoomInfo["users_num"] = sizeof($players);
                $gRoomInfo["users"] = $players; // 游戏数据
                $dbEx = GameCommon::createRoomsPlayinfo($gameRId, $gameNo, $gRoomInfo, $userid);   // 房间落地写入DB并开始发牌
                BaseEnum::Logger('取内存数据：[ROOM]--->>>' . json_encode(BaseComm::distMemoryRooms($gameNo, FALSE)), 'user-login');
                // 写入成功，游戏开始
                if ($dbEx === true) {
                    BaseEnum::Logger("房间成功写入DB：Games-(play)-，开始游戏[debug={$debugFlag}]---->>>" . $gameNo, 'user-login');
                }else{
                    BaseEnum::Logger("房间写入DB失败：Gamepork-(goo)-，写数据失败!!!! [gameNo={$gameNo}]---->>>" . $gameNo, 'user-login');
                    return FALSE;
                }

                //修改缓存,添加字段
                $gData = BaseComm::distMemoryRooms($gameNo);
                if (empty($gData)) return false;
                $deskMoney = 0;
                $extInfo = [
                    'roundIndex' => 0,//最后操作的回合数，本轮有操作才更新
                    'cardStatus' => 0,// 0:未翻牌,1:已翻牌
                    'roundType'  => -1,// 当前轮的操作类型 (-1未操作 ,0-弃牌，1-比牌，2-跟注，3-加注)
                    'roundMoney' => 0,//当前轮操作金额,默认第0轮操作底注金额
                    'totalMoney' => $roomEveryPots,//初始用户下注总金额
                    'autoBet'   => 0,//自动跟注
                    'preventDiscard' => 1, //防超时弃牌，默认开启
                    'isInRoom' => 1,//玩家还在房间,弃牌或比牌失败后离开房间不推送数据
                ];
                //$players 比 $gData['list']拓展
                if(isset($gData['lists']) && !empty($gData['lists'])) foreach ($gData['lists'] as $seatNo => &$wjInfo){
                    $wjInfo = array_merge($wjInfo,$extInfo);
                    $deskMoney = bcadd($deskMoney,$roomEveryPots,2);
                    $players[$seatNo] = array_merge($players[$seatNo],$extInfo);
                }
                BaseEnum::Logger('匹配完成补充玩家信息--->>>' . json_encode($players), 'user-login');
                $gData['maxRound'] = 20; //最大回合数
                $gData['currRound'] = 1; //当前回合数,第几轮
                $players_fd = ! empty($players) ? array_column($players, 'fd', "seatNo") : false; // 玩家FD列表；要及时推着在线等用户；
                $gData['lastSeatNo'] = -1; //最后下注位置索引,第一轮默认是-1,定时器结束后将lastSeatNo玩家所在座位号
                $gData['currSeatNo'] = 0; //默认从0号位开始操作，定时器结束将currSeatNo指向下一个玩家的座位号,判断当前操作玩家弃牌在定时器内从而清除定时器
                $gData['deskMoney'] = $deskMoney; //桌子上总筹码
                $gData['enableSeatNo'] = array_column($players,'seatNo','seatNo');//弃牌和比牌失败后数组里
                BaseComm::distMemoryRooms($gameNo,true,$gData);



//                //返回客户端数据
//                $gameResult['gstart'] = 1;
//                $gameResult['gameNo'] = $gameNo;
//                $gameResult['deskMoney'] = $deskMoney;
//                $gameResult['currRound'] = 1; //当前回合
//                $gameResult['roomInfo'] = [
//                    "gameId"=>$gameId,
//                    "everyPoints"=>$roomEveryPots, //下注最低分数,底分
//                    "smallPoints"=>$roomLastPots,// 最低准入分数
//                    "total"=>$totalJu, //至少玩的局数,1
//                    "bottomChip" => min($selectChips)/2,//底注
//                    "topChip" => max($selectChips)*2,//顶注
//                ];
//                $gameResult['players'] = $players;//玩家基本信息

                //TODO：通知所有玩家进入游戏
//                if (! empty($players_fd)) {
//                    AuthCommon::pushFrontWeb($players_fd, json_encode([ 'm' => BaseEnum::XYM_0X16, "data" => $gameResult])); // 推送相同内容
//                }

                //游戏开始(asycStartGame)
                if (!$gameOObject || empty($gameOObject) || (!empty($gameOObject) && isset($gameOObject -> baseGameName) && $gameOObject -> baseGameName != $gameName)) {
                    $gameOObject = BaseEnum::getClassObject($gameName, false);           // 创建对象；
                    BaseEnum::Logger('实例化为空：新实例化一个操作；-->>>' . json_encode(['gName'=> $gameName,"obj"=> $gameOObject]), 'user-login');
                }
                if (!empty($gameOObject)) {
                    BaseEnum::Logger('实例化：变更Name (getGameObject)--->>>' . json_encode($gameOObject), 'user-login');
                    BaseEnum::Logger("开始进入互动：Games-(play)-getClassObject，[{$gameName}]---->>>" . json_encode($gameOObject), 'user-login');
                    if (! empty($gameOObject) && method_exists($gameOObject, "asycStartGame")) {

                        // 启动游戏操作
                        $gameOObject->setGameStatus("P-" .ZjhEnum::GAME_STEP_0); // 设置游戏状态,匹配完成；
                        BaseEnum::Logger('实例化对象：' . json_encode($gameOObject), 'user-login');
                        BaseEnum::Logger("开始进入互动：Games-(play)-getClassObject，[{$gameName}]---->>>" . $gameNo, 'user-login');
                        //先不推送匹配的用户信息传过去
                        $gameOObject -> asycStartGame($gameNo, $gameRId, $players,$gRoomInfo);
                    }
                } else {
                    BaseEnum::Logger("互动失败：Games-(play)-getClassObject，[{$gameName}]----失败!!!!" . json_encode($gameOObject), 'user-login');
                }
            } else {
                /* $res = []; //列表中人数不够加入机器人
                $robotFile = EASYSWOOLE_ROOT.'/Robot/playQZNN.php';
                @exec("php {$robotFile}",$res);
                BaseEnum::Logger("执行系统函数：Games-(play)-System，[{$robotFile}]----执行".json_encode($res), 'user-login'); */


//                //TODO 启动机器人等待
//                $this->joinIntoRobots($gameRId,$loginFd,$userid,$gRoomInfo,$gameOObject);

                //TODO 进入等待(等待匹配其它玩家)
                $this->waitStartTimeOut($gameRId, $loginFd,$userid,$gRoomInfo);
            }
        } catch (\Throwable $e) {
            BaseEnum::Logger("抛出异常：玩家上桌失败[code={$e->getCode()}]---msg==>" . $e->getMessage(), 'user-login');
            $this->ResError($e->getCode(), $e->getMessage());
        }
        return true;
    }

    /**
     * 加入或创建虚拟房间号；实现和gamecommon一样，去掉了多余字段
     * @param int $roomId
     */
    protected function joinXYRooms($roomId,$roomInfo=FALSE,$player = false) {
        $currentFd = isset($player['fd']) ? intval($player['fd']) : 0 ;
        if(!$roomId || !$roomInfo || $currentFd <=0 )return false ;
        $roomNo = false;
        BaseEnum::Logger('匹配测试：(joinXYRooms)-RoomId='. $roomId. '-- player=='.json_encode($player), 'user-login');

        //加入排队
        $roomList = $this->joinGameList($roomId,$player);

        //是否可以组队成功
        $fjPlayerInfo = $this->groupRoomsUser($roomId,$roomList,$roomInfo,$roomNo);

        //是否成功
        if (isset($fjPlayerInfo) && !empty($fjPlayerInfo) && !empty($roomNo)) {
            return ['ifOpen'=>1,"roomNo"=>$roomNo,"info"=>$fjPlayerInfo];
        }
        //失败
        return FALSE;
    }

    //加入游戏列表；
    protected function  joinGameList($roomId,$player = false){
        $oneuid = isset($player['uid']) ? intval($player['uid']) : 0 ;  // 玩家ID值；
        //统一把所有参数游戏的人都放在游戏列表中去；
        $fjUser = BaseComm::distMemoryPlayer($roomId,FALSE);
        BaseEnum::Logger('Games-(joinGameList)-列队数据-->>>' . json_encode($fjUser), 'user-login');
        if(isset($fjUser) && !empty($fjUser)){
            $fjUser[$oneuid] = $player;
        }else{
            $fjUser = [$oneuid => $player];
        }
        BaseComm::distMemoryPlayer($roomId,TRUE,$fjUser);   //玩家 1 加入列表
        //BaseEnum::wirteRedisData("BaseDB:joinGameRidUsers" , json_encode($fjUser) , $roomId);//内存数据缓存写入Redis；
        BaseEnum::Logger('Games-(joinGameList)-加入列队-->>>' . json_encode($fjUser), 'user-login');
        return isset($fjUser) ? $fjUser : FALSE;    //返回当前游戏中的总人数
    }

    /**
     * 组队创建游戏桌号
     * 房间桌号都是自动分配处理的；达到人数集满就可以开局
     * @param int $roomId
     */
    protected function groupRoomsUser($roomId,$roomList = false,$fjInfo = false ,&$roomNo = false) {
        $fjUserList = array();
        if(!$roomList){
            $roomList = BaseComm::distMemoryPlayer($roomId , FALSE);  //没有排队人员
        }
        BaseEnum::Logger("排队人员数据Gamejinhua-->groupRoomsUser".json_encode($roomList),'user-login');
        $allRoomUserIds = !empty($roomList) ? array_keys($roomList) : false ;
        $gameId = isset($fjInfo['gameId']) ? intval($fjInfo['gameId']) : 0 ;
        $playNum = isset($fjInfo['playNumber']) ? intval($fjInfo['playNumber']) : 1 ; //最少玩局数
        $minDiMoney = isset($fjInfo['everyPoints']) ? intval($fjInfo['everyPoints']) : 1 ;
        $minPeop = isset($fjInfo['minPlayer']) ? intval($fjInfo['minPlayer']) : 0 ;          //最小限，0为不限；999;
        $maxPeop = (isset($fjInfo['maxPlayer']) && intval($fjInfo['maxPlayer']) > 0)  ? intval($fjInfo['maxPlayer']) : 0;    //最大限，0为不限；999;
        $duiNum = !empty($allRoomUserIds) ? sizeof($allRoomUserIds) : 0 ;

        //当前游戏中的真实现家数
        $gameDoRealNum = 0;

        //取几个人参数匹配成一个游戏队；
        $getsmall_num = $minPeop;                    //取最少人数开始；
        if ($duiNum > 0 && $duiNum >= $minPeop) {    //满足最少条件即可生成一局；
            if(isset($maxPeop) && $maxPeop > $minPeop && $maxPeop <= 999 && $duiNum >= $minPeop + 2 ){ //超出2个以上才随机取
                $maxPeop = (isset($duiNum) && $duiNum < $maxPeop) ? $duiNum : $maxPeop ;    //不能超过队的值：
                $getsmall_num = rand($minPeop,$maxPeop);                                    //取随机人数目
            }

            //取随机匹配用户；
            $getUids = (!empty($allRoomUserIds) && $duiNum >= $getsmall_num && $getsmall_num > 0) ? array_rand($allRoomUserIds,$getsmall_num) : false ;
            BaseEnum::Logger("创建游戏检测：[是否房间内人数充足: {$duiNum}] 匹配人员数：{$getsmall_num} --SUCCESS== >>" . json_encode($getUids), 'user-login');
            if ($getUids) {
                $seat = 0;
                foreach ($getUids as $vin){
                    $vuid = isset($allRoomUserIds[$vin]) ? intval($allRoomUserIds[$vin]) :0 ;
                    $vplayinfo = isset($roomList[$vuid]) ? $roomList[$vuid] : 0;
                    if (isset($vplayinfo) && !empty($vplayinfo)) {
                        //TODO 真实玩家数目 +1
                        $gameDoRealNum += 1;

                        $vplayinfo["fullName"] = $vplayinfo["name"];
                        $vplayinfo["name"] = BaseComm::hiddenUserName($vplayinfo["name"]);
                        //分配座位号；
                        $vplayinfo["seatNo"] = $seat;
                        /*
                        $vplayinfo["maxQzMutle"] = 3;   //牛牛3倍
                        //TODO 抢庄倍数： 抢庄玩家本局能承受的最大赔付金额是低注的多少倍数。炸金花可全赔
                        if ($gameId == 102) {
                            $countMaxMut = (isset($vplayinfo["points"]) && floatval($vplayinfo["points"]) > $minDiMoney) ? intval($vplayinfo["points"]/$minDiMoney) : 1;
                            $vplayinfo["maxQzMutle"] = (isset($countMaxMut) && $countMaxMut > 200) ? 200 : $countMaxMut; //最小倍数
                        }else if($gameId == 112){
                            $vplayinfo["maxQzMutle"] = 4;                           //牌九抢庄倍数最大4倍
                        }
                        */
                        unset($vplayinfo['group_id'],$roomList[$vuid]) ;            //清掉ID值；
                        $fjUserList[$seat] = $vplayinfo;                            //取用户信息；
                        $seat ++;                                                   //座位号分配
                    }
                }
                //是否列队中还有人员
                BaseComm::distMemoryPlayer($roomId,TRUE,$roomList);                    //保存用户数据

                //生成房间号等信息
                if(!empty($fjUserList)){

                    //TODO 游戏开始=== 获取房间编号
                    $roomNo = $this->openGameSuccess($gameId, $roomId, $fjUserList,$playNum,$gameDoRealNum);
                    if(!$roomNo){
                        BaseEnum::Logger("创建游戏检测：(joinGameRidUsers)-开启失败..>>>" . json_encode($fjUserList), 'user-login');
                        return FALSE;
                    }
                }
            }
        }else{
            BaseEnum::Logger("创建游戏检测：(joinGameRidUsers)-[是否房间内人数: {$duiNum}] ,至少需要人数：{$getsmall_num} --才能开始游戏...>>>" . json_encode($allRoomUserIds), 'user-login');
        }
        return !empty($fjUserList) ? $fjUserList : FALSE;
    }

    /**
     * TODO 游戏开局成功
     * TODO 组装房间的状态信息；和玩家数据(fjStatus: 0)
     */
    protected function openGameSuccess($gameId,$roomId,$gameUsers , $playNum = 1,$gamePeop = 0,$extendsArray=FALSE){
        if(!$gameId || !$roomId || empty($gameUsers)) return FALSE;
        $gameNo = BaseComm::getRoomUnioxNo($roomId);        //房间编号
        $gamePeop = ($gamePeop>0) ? $gamePeop : sizeof($gameUsers);
        $fjPlays = array(
            "isOpen"    => 1,
            "gameId"    => $gameId,
            'grid'      => $roomId,
            "gameNo"    => $gameNo,
            "fjStatus"  => ZjhEnum::GAME_STEP_0,
        );
        if (!empty($extendsArray)) {
            $fjPlays = array_merge($fjPlays,$extendsArray);
        }
        $fjPlays["isFirst"] = 1 ;                                           //开始第一轮
        $fjPlays["create"] = BaseEnum::getNowTime(FALSE);                   //创建时间
        $fjPlays["lists"] = $gameUsers;                                     //创建时间
        BaseComm::distMemoryRooms($gameNo ,TRUE,$fjPlays);                  //保存用户数据
        //首先用FD查询当前玩家进过哪些房间信息；
        $allUids = array_column($gameUsers, "uid");
        BaseComm::distLastGameNoListRedis($allUids,TRUE, json_encode([$gameNo,$roomId]));        //缓存玩家最近的房间号；
        BaseEnum::Logger("组建游戏新桌号：(joinGameRidUsers)-=={$gameNo} -- >>>" . json_encode($fjPlays), 'user-login');
        //$redisobj -> setRedisValue(self::ONLINE_ROOMS_LIST_KEY.$roomNo, json_encode($fjPlays),self::$login_longtime);               //缓存游戏信息；

        //TODO 在线玩家数据（加入）
        BaseComm::changeOnLines($gameId,$gamePeop,0);
        return $gameNo;
    }

    /**
     * 玩家看牌操作,跟注和比牌翻倍，加注筹码值翻倍
     */
    public function playFlip()
    {
        $loginFd = $this->paramsBean->getFd();
        $data = $this->paramsBean->getData(true);
        $gameRId = isset($data['gameRoomId']) ? intval($data['gameRoomId']) : 0; // 房间ID；
        $gameNo = isset($data['gameNo']) ? $data['gameNo'] : ""; // 游戏号；
        try {
            //TODO：登录验证
            $loginUser = AuthCommon::getLoginUser($loginFd);
            $userid = isset($loginUser["uid"]) ? intval($loginUser["uid"]) :0 ;
            if(empty($loginUser) || $userid <= 0){
                $this->ResError(BaseEnum::MSG_0XF7,"玩家未登录，或玩家已掉线请重试", 1);   //重新登录
                return true;
            }
            if (! $gameRId || ! $gameNo) {
                $this->ResError(BaseEnum::MSG_0XF2, "提交翻牌参数丢失");
                return true;
            }
            $userPoints = isset($loginUser['points']) ? floatval($loginUser['points']) :0;
            // 查询游戏数据；
            $fjDetail = BaseComm::distMemoryRooms($gameNo,FALSE);
            $playList = (isset($fjDetail['lists']) && ! empty($fjDetail['lists'])) ? $fjDetail['lists'] : false;
            $playFds = !empty($playList) ? array_column($playList, "fd","seatNo") : false ;

            $loginSiteNo = !empty($playFds) ? array_search($loginFd, $playFds) : -1; //登录用户所在位置；
            $wjInfo = isset($playList[$loginSiteNo]) ? $playList[$loginSiteNo]  : FALSE ;//操作玩家
            if ($loginSiteNo < 0 || !$wjInfo || $wjInfo['cardStatus']==1) {
                return false;
            }
            //看牌修改玩家看牌状态，跟注和比牌,加注的筹码值
            $wjInfo['cardStatus'] = 1;
            $cards = $wjInfo['cards'] ?? [];
            $cardsLevel = $wjInfo['cardsLevel'] ?? 1;
            $minBet = 2*$wjInfo['minBet'] ?? 0;
            $chips = $wjInfo['chips'] ?? [];
            foreach ( $chips as &$v) {
                $v = 2*$v;
            }
            $fjDetail["lists"][$loginSiteNo] = $wjInfo;
            BaseComm::distMemoryRooms($gameNo, TRUE,$fjDetail); // 保存用户数据

            if (!empty($playFds)) {
                $data = [
                    "seatNo" => $loginSiteNo,//当前玩家座位号
                    "text" => "看牌",//推送给全部
                    "minBet" => $minBet,//当前玩家跟注筹码（推送给自己）
                    "chips" => $chips,//当前玩家加注筹码 （推送给自己）
                    'cards' => $cards,//牌 （推送给自己）
                    'cardsLevel' => $cardsLevel,//牌型 （推送给自己）
                ];
                // 推送给所有玩家，已看牌；
                AuthCommon::pushFrontWeb($playFds, json_encode([ 'm' => BaseEnum::XYM_0X71, "data" => $data ])); // 推送
            }
        } catch (\Throwable $e) {
            BaseEnum::Logger("抛出异常：[code={$e->getCode()}]---msg==>" . $e->getMessage(), 'user-login');
        }
        return FALSE;
    }

    /**
     * 玩家比牌,点击比牌按钮，返回可比牌的座位号,不需改变内存所以独立出来
     */
    public function playPreCompare(){
        $loginFd = $this->paramsBean->getFd();
        $data = $this->paramsBean->getData(true);
        $gameRId = isset($data['gameRoomId']) ? intval($data['gameRoomId']) : 0 ; //游戏房间
        $gameNo = isset($data['gameNo']) ? $data['gameNo'] : "";
        try {
            //TODO：登录验证
            $loginUser = AuthCommon::getLoginUser($loginFd);
            $userid = isset($loginUser["uid"]) ? intval($loginUser["uid"]) :0 ;
            if(empty($loginUser) || $userid <= 0){
                $this->ResError(BaseEnum::MSG_0XF7,"玩家未登录，或玩家已掉线请重试", 1);   //重新登录
                return true;
            }

            if (!$gameRId || !$gameNo) {
                $this->ResError(BaseEnum::MSG_0XF2, "游戏类型参数丢失");
                return true;
            }
            //TODO 游戏数据
            $fjDetail = BaseComm::distMemoryRooms($gameNo,FALSE);
            $playList = $fjDetail["lists"] ?? [] ;
            $playFds = !empty($playList) ? array_column($playList, "fd","seatNo") : false ;
            $currSeatNo = $fjDetail['currSeatNo'] ?? -1;
            //取座位号
            $loginSiteNo = !empty($playFds) ? array_search($loginFd, $playFds) : -1; //登录用户所在位置；
            if($loginSiteNo < 0 || $currSeatNo < 0) return FALSE;
            if ($loginSiteNo != $currSeatNo){
                $this->ResError(BaseEnum::MSG_0XFD, "玩家非下注状态");
                return true;
            }
            $enableSeatNo = $fjDetail['enableSeatNo'] ?? [];
            unset($enableSeatNo[$loginSiteNo]); //除了玩家自己,剩余可用的座位号
            $pushdata = ['m'=>BaseEnum::XYM_0X73,'data'=>['seatNo'=>$enableSeatNo]];
            AuthCommon::pushFrontWeb($loginFd,json_encode($pushdata));
            return FALSE;
        } catch (\Throwable $e) {
            BaseEnum::Logger("玩家操作异常". $e->getMessage(), 'user-login');
        }
        return FALSE;
    }

    /**
     * 玩家执行操作,不在定时器内弃牌的直接修改内存，返回弃牌，在定时器内的弃牌要停掉定时器，修改内存.
     * 下注修改内存，停掉定时器，执行回调中不用再次修改内存，玩家加注情况下修改可操作性玩家的最小下注,加注筹码（需要看每个玩家看牌与否），并且推送每个玩家影响的筹码值
     * 比牌修改内存，停掉定制器，返回比牌失败玩家信息
     * 游戏回调函数判断轮数，玩家筹码值，达到最大轮数20，自动比牌，玩家筹码值不够下注，孤注一掷，只剩一个玩家，该玩家获胜
     * 定时器结束修改lastSeatNo,currSeatNo,currRound
     * 只修改当前玩家的roundIndex,roundType,roundMoney,totalMoney,房间的enableSeatNo,deskMoney,fjStatus。
     */
    public function goBet() {
        $loginFd = $this->paramsBean->getFd();
        $data = $this->paramsBean->getData(true);
        $gameRId = isset($data['gameRoomId']) ? intval($data['gameRoomId']) : 0 ;   //游戏房间
        $gameNo = isset($data['gameNo']) ? $data['gameNo'] : "" ;                   //游局号
        $htype = isset($data['htype']) ? intval($data['htype']) : 0 ;               //操作类型
        $money = isset($data['money']) ? floatval($data['money']) : 0 ;
        $seatNo = isset($data['seaatNo']) ? $data['seatNo'] : "";
        try {
            //TODO：登录验证
            $loginUser = AuthCommon::getLoginUser($loginFd);
            $userid = isset($loginUser["uid"]) ? intval($loginUser["uid"]) :0 ;
            if(empty($loginUser) || $userid <= 0){
                $this->ResError(BaseEnum::MSG_0XF7,"玩家未登录，或玩家已掉线请重试", 1);   //重新登录
                return true;
            }

            if (!$gameRId || !$gameNo) {
                $this->ResError(BaseEnum::MSG_0XF2, "游戏类型参数丢失");
                return true;
            }
            $userPoints = isset($loginUser['points']) ? floatval($loginUser['points']) :0;
            //TODO 游戏数据
            $fjDetail = BaseComm::distMemoryRooms($gameNo,FALSE);
            $playList = isset($fjDetail["lists"]) ? $fjDetail["lists"] : FALSE ;
            $playFds = !empty($playList) ? array_column($playList, "fd","seatNo") : false ;
            $currRound = isset($fjDetail["currRound"]) ? intval($fjDetail["currRound"]) : 1 ; //取第几轮；
            $currSeatNo = isset($fjDetail['currSeatNo']) ? intval($fjDetail['currSeatNo']) : -1;//等待操作的玩家
            $deskMoney = isset($fjDetail["deskMoney"]) ? floatval($fjDetail["deskMoney"]) :0 ;
            //取座位号
            $loginSiteNo = !empty($playFds) ? array_search($loginFd, $playFds) : -1; //登录用户所在位置；
            $currUser = $playList[$loginSiteNo] ?? FALSE ;//操作玩家
            if($loginSiteNo < 0 || !$currUser || $currSeatNo < 0) return FALSE;
            $enableSeatNo = $fjDetail['enableSeatNo'] ?? [];

            //TODO  跟注、加注 type = 2,3
            if (in_array($htype, [ZjhEnum::HANDLE_TYPE_2,ZjhEnum::HANDLE_TYPE_3],TRUE) && $money > 0) {
                //非下注状态不能比牌
                if ($loginSiteNo != $currSeatNo){
                    $this->ResError(BaseEnum::MSG_0XFD, "玩家非下注状态");
                    return true;
                }
                $oldMoney = isset($currUser['totalMoney']) ? $currUser['totalMoney'] : 0;
                //TODO  登录玩家信息变更,覆盖
                $currUser['roundType'] = $htype;
                $currUser['roundIndex'] = $currRound;         //同步本轮已操作
                $currUser['roundMoney'] = floatval($money);             //本轮操作金钱
                $currUser['totalMoney'] = floatval(bcadd($oldMoney,$money,3));
                $fjDetail['deskMoney'] = floatval(bcadd($deskMoney,$money,3));

                // TODO 加注改变剩余可操作性玩家的跟注比牌筹码值
                if($htype == ZjhEnum::HANDLE_TYPE_3){
                    $minBet = $currUser['cardStatus'] == 1 ? $money/2 : $money;
                    foreach ($enableSeatNo as $v) {
                        $player = $playList[$v];
                        $player['minBet'] = $player['cardStatus']==1 ? 2*$minBet : $minBet;
                        $playList[$v] = $player;
                    }
                }
            }
            //TODO  弃牌操作  type = 0,如果本轮之前已经下注,弃牌操作将直接覆盖本轮的下注操作
            else if($htype === ZjhEnum::HANDLE_TYPE_0){
                $currUser['roundIndex'] = $currRound;
                $currUser['roundType'] = ZjhEnum::HANDLE_TYPE_0;
                $currUser['roundMoney'] = 0.00;
                unset($fjDetail['enableSeatNo'][$loginSiteNo]); //房间可继续下注的座位,比牌失败的玩家也要unset掉
                //如果提前弃牌
                if ($loginSiteNo != $currSeatNo){
                    $pushdata = [
                        'm'=>BaseEnum::XYM_0X73,
                        'data'=>[
                            'seatNo'=>$loginSiteNo,//弃牌的座位号
                            'htype' => $htype
                        ]
                    ];
                }

            }
            //TODO  比牌操作  type = 1
            else if($htype === ZjhEnum::HANDLE_TYPE_1){
                if ($loginSiteNo != $currSeatNo){
                    $this->ResError(BaseEnum::MSG_0XFD, "玩家非下注状态");
                    return true;
                }

                $otherUser = $playList[$seatNo] ?? false;

                //发起比牌过程中有可能被比牌用户已弃牌,需重新比牌。
                if(!in_array($seatNo,$enableSeatNo) || !$otherUser){
                    $this->ResError(BaseEnum::MSG_0XF2, "游戏参数错误请重新比牌");
                    return true;
                }
                $oldMoney = isset($currUser['totalMoney']) ? $currUser['totalMoney'] : 0;
                $currUser['roundIndex'] = $currRound;
                $currUser['roundType'] = ZjhEnum::HANDLE_TYPE_1;
                $currUser['roundMoney'] = floatval($money);
                $currUser['totalMoney'] = floatval(bcadd($oldMoney,$money,3));
                $fjDetail['deskMoney'] = floatval(bcadd($deskMoney,$money,3));

                $failPlayer = ZjhEnum::gatherWhoWin($currUser,$otherUser,$payPlayer);
                $failSeatNo = $failPlayer['seatNo'] ?? -1;

                if ($failSeatNo < 0) return false;
                //可用位置删掉比牌失败的玩家座位号
                unset($fjDetail['enableSeatNo'][$failSeatNo]);

                $pushdata = [
                    'm'=>BaseEnum::XYM_0X73,
                    'data'=>[
                        'seatNo' => $loginSiteNo,
                        'failSeatNo'=>$failSeatNo,//比牌失败的座位号
                        'htype' => $htype,//比牌失败
                    ]
                ];
                //

            }
            //TODO  触发 孤注一掷  type = 4
            else if($htype === ZjhEnum::HANDLE_TYPE_4){      //所有的话，后面的玩家只有两种选择====> 弃牌和ALL IN
                $oldMoney = isset($currUser['total_money']) ? $currUser['total_money'] : 0;
                $money = floatval($currUser["points"]);
                $currUser['roundType'] = ZjhEnum::HANDLE_TYPE_4;
                $currUser['roundMoney'] = $money;
                $currUser['roundIndex'] = $currRound;
                $currUser['totalMoney'] = floatval(bcadd($oldMoney, $money,3));               // 玩家下注总额
                $fjDetail['deskMoney'] = floatval(bcadd($deskMoney,$money,3));
            }
            //TODO  保存玩家游戏数据
            $playList[$loginSiteNo] = $currUser;
            $fjDetail['lists'] = $playList;
            BaseEnum::Logger("玩家操作： (GameZhajinhua)---type={$htype},money={$money}  info=>" . json_encode($currUser), 'user-login');
            BaseComm::distMemoryRooms($gameNo,TRUE,$fjDetail);
            //当前玩家非弃牌停掉定时器，如果弃牌是在定时器内或者$enableseat剩下一人停掉定时器进入结算
            $enableSeatNo = $fjDetail['enableSeatNo'] ?? [];//弃牌之后可能只剩下一个玩家
            if($htype != ZjhEnum::HANDLE_TYPE_0 || $loginSiteNo == $currSeatNo || sizeof($enableSeatNo) == 1){
                PlayHelp::getInstance()->setCommTimerStop($gameNo,true);
            }

            if ($loginSiteNo == $currSeatNo){
                PlayHelp::getInstance()->setCommTimerStop($gameNo,true);
            }
            if (isset($pushdata) && !empty($pushdata)){
                AuthCommon::pushFrontWeb($playFds,json_encode($pushdata));
            }
            return FALSE;
        } catch (\Throwable $e) {
            BaseEnum::Logger("玩家操作异常". $e->getMessage(), 'user-login');
        }
        return FALSE;
    }

}